# -*- coding: utf-8 -*-

import json

from django.utils.decorators import method_decorator
from django.utils.encoding import smart_unicode
from django.views.decorators.http import require_GET, require_POST
from django.views.generic import TemplateView

from admin.views.agentpay import CHANNEL_MAP
from common.admin import db as user_db
from common.admin.model import ROLE
from common.channel import admin_db as chn_db
from common.channel.model import CHANNEL_NAME
from common.mch.db import set_mch_test_chn_id
from common.utils import track_logging
from common.utils.api import token_required
from common.utils.decorator import response_wrapper
from common.utils.exceptions import ParamError
from common.utils.tz import utc_to_local_str

_LOGGER = track_logging.getLogger(__name__)


@require_GET
@response_wrapper
@token_required
def get_chns(req):
    query_dct = req.GET.dict()
    chn_ids = json.loads(query_dct.get('chn_ids', '[]'))
    channels = chn_db.get_channels_in_ids(chn_ids)

    mch_ids = user_db.get_mchids_by_user(req.user_id)
    _LOGGER.info('ChannelView get mchs: %s, ', mch_ids)

    p_info = dict()
    for chn in channels:
        if len(mch_ids) == 0 or str(chn.mch_id) in mch_ids:
            p_info[chn.id] = {
                'name': chn.name,
                'service_name': chn.service_name,
                'mch_id': chn.mch_id,
            }
    return {'dict': p_info}


@require_GET
@response_wrapper
# @token_required
def get_channeL_type(req):
    return {'dict': CHANNEL_NAME}


class ChannelView(TemplateView):
    def get(self, req):
        query_dct = req.GET.dict()
        # query_dct[u'service_name'] = {"$neq":'test'}
        cond = user_db.get_mchids_filter_by_user(req.user_id)
        if cond and not query_dct.get('mch_id', ''):
            query_dct['mch_id'] = cond
        user_db.filter_user_channels(req.user_id, query_dct, 'id')
        _LOGGER.info('ChannelView get mchs: %s, ', query_dct)
        items, total_count = chn_db.list_channel(query_dct)

        resp_items = []
        for item in items:
            data = item.as_dict()
            data['created_at'] = utc_to_local_str(data['created_at'])
            data['updated_at'] = utc_to_local_str(data['updated_at'])
            resp_items.append(data)

        return {'list': resp_items, 'page': query_dct.get('$page', 1),
                'size': len(resp_items), 'total_count': total_count}

    def post(self, req):
        param_dct = json.loads(req.body)
        if param_dct.get('rate') is None or param_dct['rate'] == '':
            raise ParamError('rate can not be empty')
        if param_dct.get('service_name') is not None and 'quota' in param_dct.get('service_name'):
            if param_dct.get('quotas') is None or param_dct['quotas'] == '':
                raise ParamError('quotas can not be empty')
            quotas = [float(y) for y in param_dct['quotas'].split(',')]
        chn_db.upsert_channel(param_dct)
        return {}

    def put(self, req):
        return self.post(req)

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(ChannelView, self).dispatch(*args, **kwargs)


class SingleChannelView(TemplateView):
    def get(self, req, chn_id):
        channel = chn_db.get_channel(id=int(chn_id))
        data = channel.as_dict()
        data['created_at'] = utc_to_local_str(data['created_at'])
        data['updated_at'] = utc_to_local_str(data['updated_at'])
        j = json.loads(data['info'])
        data['min_amount'] = j.get('min_amount', 1)
        data['max_amount'] = j.get('max_amount', 50000)
        data['daily_start'] = j.get('daily_open_time', {}).get('start', 0)
        data['daily_end'] = j.get('daily_open_time', {}).get('end', 24)
        data['daily_amount'] = j.get('incr_risk', {}).get('daily', {}).get('amount', 10000000)
        data['daily_count'] = j.get('incr_risk', {}).get('daily', {}).get('count', 10000000)
        data['hourly_amount'] = j.get('incr_risk', {}).get('hourly', {}).get('amount', 10000000)
        data['hourly_count'] = j.get('incr_risk', {}).get('hourly', {}).get('count', 10000000)
        data['minutely_amount'] = j.get('incr_risk', {}).get('minutely', {}).get('amount', 10000000)
        data['minutely_count'] = j.get('incr_risk', {}).get('minutely', {}).get('count', 10000000)
        return data

    def post(self, req, chn_id):
        return self.put(req, chn_id)

    def put(self, req, chn_id):
        query_dct = json.loads(smart_unicode(req.body))
        json.loads(query_dct['info'])
        if query_dct.get('levels'):
            query_dct['levels'] = query_dct['levels'].replace(' ', '').replace(u'，', ',')
            if query_dct['levels'][-1:] == ',':
                query_dct['levels'] = query_dct['levels'][:-1]
            levels = [int(x) for x in query_dct['levels'].split(',')]
        if query_dct.get('quotas'):
            query_dct['quotas'] = query_dct['quotas'].replace(' ', '').replace(u'，', ',')
            if query_dct['quotas'][-1:] == ',':
                query_dct['quotas'] = query_dct['quotas'][:-1]
            quotas = [float(y) for y in query_dct['quotas'].split(',')]
        return {}

    def patch(self, req, chn_id):
        query_dct = json.loads(smart_unicode(req.body))
        if query_dct.get('levels'):
            query_dct['levels'] = query_dct['levels'].replace(' ', '').replace(u'，', ',')
            if query_dct['levels'][-1:] == ',':
                query_dct['levels'] = query_dct['levels'][:-1]
            levels = [int(x) for x in query_dct['levels'].split(',')]
        if query_dct.get('quotas'):
            query_dct['quotas'] = query_dct['quotas'].replace(' ', '').replace(u'，', ',')
            if query_dct['quotas'][-1:] == ',':
                query_dct['quotas'] = query_dct['quotas'][:-1]
            quotas = [float(y) for y in query_dct['quotas'].split(',')]

        json.loads(query_dct.get('info', '{}'))
        channel = chn_db.get_channel(id=int(chn_id))
        info = json.loads(channel.info)
        pay_type = channel.service_name
        if pay_type in ['quota_alipay', 'quota_wxpay', 'quota_hydra']:
            if 'service_name' in req.DATA.keys():
                if str(req.DATA['service_name']) in ['quota_alipay', 'quota_wxpay', 'quota_hydra']:
                    judge_quota(req, channel)
                else:
                    pass
            else:
                judge_quota(req, channel)
        else:
            if 'service_name' in req.DATA.keys():
                if str(req.DATA['service_name']) in ['quota_alipay', 'quota_wxpay', 'quota_hydra']:
                    judge_quota(req, channel)
                else:
                    pass

        if query_dct.get('quotas') and pay_type in ['quota_alipay', 'quota_wxpay', 'quota_hydra']:
            if 'max_amount' in req.DATA.keys():
                max_amount = req.DATA['max_amount']
            else:
                max_amount = info.get('max_amount', 1000000)
            max_quota = max(quotas)
            if max_quota > max_amount:
                raise ParamError(u'“定额列表”最大值大于“设定最大金额”栏目值, max(quota) > max_amount')

        chn_db.upsert_channel(query_dct, int(chn_id))
        chn_db.modify_channel_info(query_dct, int(chn_id))
        chn_db.modify_channels_ip_white_lists_according_chn_type(int(chn_id))
        return {}

    def delete(self, req, chn_id):
        if req.user.role != ROLE.ADMIN:
            raise ParamError(u'只有管理员才能删除通道')
        chn_db.delete_channel(int(chn_id))
        _LOGGER.info('delete channel: %s, user: %s', chn_id, req.user_id)
        return {}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(SingleChannelView, self).dispatch(*args, **kwargs)


@require_POST
@response_wrapper
@token_required
def set_test_channel(req):
    query_dct = json.loads(smart_unicode(req.body))
    # todo 目前出现测试通道覆盖正式通道的情况，待核实
    _LOGGER.info('set_test_channel, query_dct: %s, user_id: %s, %s', req.body, req.user_id, req.user.nickname)
    channel_id = int(query_dct['id'])
    mch_id = int(query_dct['mch_id'])

    c = chn_db.make_channel_test(channel_id, mch_id)
    set_mch_test_chn_id(mch_id, c.id)

    # test_channel_id = get_mch_test_chn_id(mch_id)

    # if test_channel_id is None:
    #     c = chn_db.make_channel_test(channel_id, mch_id)
    #     set_mch_test_chn_id(mch_id, c.id)
    # else:
    #     chn_db.set_channel_test(channel_id, test_channel_id)
    return {'result': 'success'}


@require_POST
@response_wrapper
@token_required
def get_channel_balance(req):
    query_dct = json.loads(smart_unicode(req.body))
    _LOGGER.info('get_channel_balance, query_dct: %s, user_id: %s, %s', req.body, req.user_id, req.user.nickname)
    chn_id = int(query_dct['id'])
    chn = chn_db.get_channel(id=int(chn_id))
    if chn.chn_type in CHANNEL_MAP.keys():
        chn_handler = CHANNEL_MAP[chn.chn_type]
        return {'balance': chn_handler.query_balance(chn.info)}
    else:
        raise ParamError(u'该通道余额查询功能未接入')


def judge_quota(req, channel):
    if 'quotas' in req.DATA.keys():
        if str(req.DATA['quotas']) != '':
            pass
        else:
            raise ParamError(u'配置定额支付时定额列表不允许为空')
    else:
        if channel.as_dict()['quotas']:
            pass
        else:
            raise ParamError(u'配置定额支付时定额列表不允许为空')
